package com.lyn.tencent_health_code.config;

import com.lyn.tencent_health_code.annotation.Login;
import com.lyn.tencent_health_code.entity.RequestResult;
import com.lyn.tencent_health_code.utils.RedisUtil;
import com.lyn.tencent_health_code.utils.SpringUtils;
import com.lyn.tencent_health_code.utils.TextUtils;
import com.lyn.tencent_health_code.utils.TokenUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.lang.reflect.Method;

/**
 * 拦截器
 *
 * @author almost
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    private Logger logger = LoggerFactory.getLogger(InterceptorConfig.class);

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyHandlerInterceptor()).addPathPatterns("/**");
    }

    private class MyHandlerInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            return examination(request, response, handler);

        }

        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
        }

        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
        }
    }

    /**
     * 检查校验
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    private boolean examination(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //检查消息对象是否是接口请求
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        if (method.isAnnotationPresent(Login.class)) {
            String token = TokenUtils.getToken(request);
            if (TextUtils.isEmpty(token)) {
                returnRequestResult(0, "请登录", response);
                logger.info("请登录1");
                return false;
            }
            RedisUtil redisUtil = SpringUtils.getBean(RedisUtil.class);
            Object o = redisUtil.get(token);
            if ((o instanceof String)) {
                if (token.equals(String.valueOf(o))) {
                    redisUtil.set(token, token, TokenUtils.EXPIRE_DATE);
                    return true;
                }
            }
            returnRequestResult(0, "请登录", response);
            logger.info("请登录2");
            return false;
        }
        return true;
    }

    /**
     * 返回请求
     *
     * @param code
     * @param message
     * @param response
     */
    private void returnRequestResult(int code, String message, HttpServletResponse response) {
        if (response == null) {
            return;
        }
        PrintWriter writer = null;
        try {
            RequestResult result = new RequestResult();
            result.setCode(code);
            result.setMessage(message);
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/json; charset=utf-8");
            writer = response.getWriter();
            writer.append(result.toString());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                writer.flush();
                writer.close();
            }
        }
    }
}
